"""
创建和使用线程正确的姿势 ---> 创建线程后，要实现对线程对象的重复利用
不要频繁的创建和释放线程，因为这两个操作本身也有比较大的开销

在进行商业项目开发时，如果要是多线程，基本上都会使用一种叫线程池的技术
线程池 ---> 一个容器，提前放置好若干个线程，用的时候直接从线程池获取线程，
用完了之后，将线程对象交还给线程池，使用线程的过程中没有创建和释放的开销，
这是一种典型的空间换时间的技术。
时间和空间是不可调和的矛盾，硬件和软件在逻辑上是等效的
科学的边界是哲学，哲学的边界是宗教（神学）
"""
import random
import time
import threading
from concurrent.futures.thread import ThreadPoolExecutor

import requests


def download_picture(url):
    # current_thread()函数可以获取当前正在执行的线程对象
    print(threading.current_thread().name)
    resp = requests.get(url)
    filename = url[url.rfind('/') + 1:]
    with open(f'image360/{filename}', 'wb') as file:
        file.write(resp.content)
    return random.randint(1, 100)


def main():
    resp = requests.get('https://image.so.com/zjl?ch=beauty&sn=0')
    data_dict = resp.json()
    futures = []
    # 创建线程池对象
    with ThreadPoolExecutor(max_workers=16) as pool:
        start = time.time()
        for image_dict in data_dict['list']:
            url = image_dict['qhimg_url']
            # 线程池的submit方法会返回一个Future对象
            f = pool.submit(download_picture, url)
            futures.append(f)
        # 等待线程池中所有线程执行结束
        for f in futures:
            print(f.result())
        end = time.time()
        print(f'执行时间: {end - start:.3f}秒')


if __name__ == '__main__':
    main()
